#ifndef _TBVEC2_H_
#define _TBVEC2_H_

#include "TBSettings.h"

#include "TBMath.h"

namespace tb
{

	class TB_DLL_FUNC Vec2
	{

	public:

		// ================================
		// Static methods
		// ================================

		static Vec2 _RANDOM(float a_Min, float a_Max);

		// ================================
		// Constructors
		// ================================

		Vec2();
		Vec2(float a_X, float a_Y);
		Vec2(float* a_Vector);
		Vec2(const Vec2& a_Copy);
		~Vec2();

		// ================================
		// Conversion
		// ================================

		Vec2& FromAngle(float a_Degrees);
		Vec2& FromPolarCoordinates(float a_Degrees, float a_Length);

		Vec2& ToPolarCoordinates(float& a_Length, float& a_Radians);
		Vec2& ToOpenGLVector(float* a_Target);

		// ================================
		// Assignment & Access
		// ================================

		Vec2& operator = (const Vec2& a_Point);
		Vec2& operator = (float a_Value);
		float& operator [] (int a_Member);
		float operator [] (int a_Member) const;

		// ================================
		// Operators
		// ================================

		Vec2 operator - () const;

		Vec2& operator += (const Vec2& a_Other);
		Vec2 operator + (const Vec2& a_Other) const;

		Vec2& operator -= (const Vec2& a_Other);
		Vec2 operator - (const Vec2& a_Other) const;

		Vec2& operator *= (float a_Scalar);
		Vec2& operator *= (const Vec2& a_Other);
		Vec2 operator * (float a_Value) const;
		Vec2 operator * (const Vec2& a_Other) const;
		inline friend Vec2 operator * (float a_Scaler, const Vec2& a_Vec)
		{
			return Vec2(
				a_Vec.x * a_Scaler, 
				a_Vec.y * a_Scaler
			);
		}

		Vec2& operator /= (float a_Value);
		Vec2& operator /= (const Vec2& a_Other);
		Vec2 operator / (float a_Value) const;
		Vec2 operator / (const Vec2& a_Other) const;

		// ================================
		// Comparisons
		// ================================

		bool operator == (const Vec2& a_Point) const;
		bool operator == (float a_Value) const;

		bool operator != (const Vec2& a_Point) const;
		bool operator != (float a_Value) const;

		bool operator > (const Vec2& a_Point) const;
		bool operator > (float a_Value) const;

		bool operator >= (const Vec2& a_Point) const;
		bool operator >= (float a_Value) const;

		bool operator < (const Vec2& a_Point) const;
		bool operator < (float a_Value) const;

		bool operator <= (const Vec2& a_Point) const;
		bool operator <= (float a_Value) const;

		bool IsEqual(const Vec2& a_Other, float a_Delta) const;
		bool IsEqual(float a_Value, float a_Delta) const;

		// ================================
		// Functions
		// ================================

		Vec2& Clear();

		float GetSquaredLength() const;
		float GetLength() const;

		Vec2& Reverse();
		Vec2 GetReversed() const;

		Vec2& PerpendicularLeft();
		Vec2 GetPerpendicularLeft() const;

		Vec2& PerpendicularRight();
		Vec2 GetPerpendicularRight() const;

		Vec2& Reciprocral();
		Vec2 GetReciprocal() const;

		Vec2& Normalize();
		Vec2 GetNormalized() const;

		float GetDotProduct(const Vec2& a_Other) const;

		float GetSquaredDistanceBetween(const Vec2& a_Other) const;
		float GetDistanceBetween(const Vec2& a_Other) const;

		float GetAngle() const;
		float GetAngleBetween(const Vec2& a_Other) const;

		Vec2& DirectionTo(const Vec2& a_Other);
		Vec2 GetDirectionTo(const Vec2& a_Other) const;

		// ================================
		// Interpolation
		// ================================

		Vec2& Lerp(const Vec2& a_Other, float a_Percentage);
		Vec2 GetLerp(const Vec2& a_Other, float a_Percentage) const;

		Vec2& Slerp(const Vec2& a_Other, float a_Percentage);
		Vec2 GetSlerp(const Vec2& a_Other, float a_Percentage) const;

		Vec2& SlerpNormalized(const Vec2& a_Other, float a_Percentage);
		Vec2 GetSlerpNormalized(const Vec2& a_Other, float a_Percentage) const;

		// ================================
		// Data
		// ================================

		float x, y;

	}; // class Vec2

}; // namespace tb

#include "TBVec2.inl"

#endif